package com.shandao.shangxiu.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.widget.ImageView;
import android.widget.Toast;

/**
 * 拍照、从相册选图片
 */
public class TakePhotoTools {

	public static final int CAMERA = 1;
	public static final int ALBUM = 2;
	public static final int PHOTO_REQUEST_CUT = 3;
	public static final int MAX_SIZE = 150;
	public static String fileName;
	static DisplayMetrics displayMetrics = new DisplayMetrics();

	/**
	 * 从相册或相机获取图片 启动相机或相册
	 */
	public static void startCameraOrGallery(Activity context, int type) {
		try {
			Intent intent;
			if (!isExternalStorageWritable()) {
				ToastUtils.show("请检查是否有SD卡");
				return;
			}
			fileName = getFileName();

			if (type == CAMERA) {

				intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(new File(fileName)));

			} else {
				intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

			}

			context.startActivityForResult(intent, type);
		} catch (Exception e) {
			// TODO: handle exception
		}

	}

	/**
	 * 
	 * @param uri
	 * @param size
	 */
	// public static void startPhotoZoom(Activity context,Uri uri, int size) {
	//
	// Intent intent = new Intent("com.android.camera.action.CROP");
	// intent.setDataAndType(uri, "image/*");
	// // crop为true是设置在开启的intent中设置显示的view可以剪裁
	// intent.putExtra("crop", "true");
	//
	// // aspectX aspectY 是宽高的比例
	// intent.putExtra("aspectX", 1);
	// intent.putExtra("aspectY", 1);
	//
	// // outputX,outputY 是剪裁图片的宽高
	// intent.putExtra("outputX", size);
	// intent.putExtra("outputY", size);
	// intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new
	// File(fileName)));
	// intent.putExtra("return-data", false);//若为false则表示不返回数据
	// context.startActivityForResult(intent, PHOTO_REQUEST_CUT);
	// }
	/**
	 * 
	 * @param uri
	 * @param size
	 */
	public static void startPhotoZoom(Activity context, Uri uri, int size) {

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		// crop为true是设置在开启的intent中设置显示的view可以剪裁
		intent.putExtra("crop", "true");

		// aspectX aspectY 是宽高的比例
		intent.putExtra("aspectX", 1);
		intent.putExtra("aspectY", 1);

		// outputX,outputY 是剪裁图片的宽高
		// intent.putExtra("outputX", size);
		// intent.putExtra("outputY", size);
		intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(new File(fileName)));
		intent.putExtra("return-data", false);// 若为false则表示不返回数据
		context.startActivityForResult(intent, PHOTO_REQUEST_CUT);
	}

	/**
	 * 
	 * @param context
	 * @param uri
	 * @param w
	 * @param h
	 */
	public static void startPhotoZoom(Activity context, Uri uri, int w, int h) {

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		// crop为true是设置在开启的intent中设置显示的view可以剪裁
		intent.putExtra("crop", "true");

		// aspectX aspectY 是宽高的比例
		intent.putExtra("aspectX", w);
		intent.putExtra("aspectY", h);

		// outputX,outputY 是剪裁图片的宽高
		intent.putExtra("outputX", w);
		intent.putExtra("outputY", h);
		intent.putExtra(MediaStore.EXTRA_OUTPUT,
				Uri.fromFile(new File(fileName)));
		intent.putExtra("return-data", false);// 若为false则表示不返回数据
		context.startActivityForResult(intent, PHOTO_REQUEST_CUT);
	}

	/* Checks if external storage is available for read and write */
	public static boolean isExternalStorageWritable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}

	
	/**
	 * 生成文件路径和文件名
	 * 
	 * @return
	 */
	private static String getFileName() {

		String saveDir = Environment.getExternalStorageDirectory()
				+ "/nahuikou/images";
		File file = new File(saveDir);
		if (!file.exists()) {
			file.mkdirs();// 创建文件夹
		}
		// 用日期作为文件名，确保唯一性
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		String fileName = saveDir + File.separator + dateFormat.format(date)
				+ ".jpg";
		return fileName;
	}

	/*
	 * 获取图片
	 */
//	public static Bitmap getPhoto(Activity context, Uri originUri) {
//
//		context.getWindowManager().getDefaultDisplay()
//				.getMetrics(displayMetrics);
//		Bitmap bitmap = null;
//		// 通过URI获取原始图片path
//		fileName = getRealPath(context, originUri);
//
//		bitmap = decodeSampledBitmapFromResource(fileName,
//				displayMetrics.widthPixels, displayMetrics.heightPixels);
//		// 是否旋转图片
//		int degree = getPictureDegree(fileName);
//		if (degree > 0) {
//			bitmap = rotaingImage(degree, bitmap);
//		}
//		Bitmap bit = compressImage(bitmap, MAX_SIZE);
////		if (data != null) {
////			fileName = getFileName();
////		}
//		BufferedOutputStream bos;
//		try {
//			bos = new BufferedOutputStream(new FileOutputStream(fileName));
//			// 采用压缩转档方法
//			bit.compress(Bitmap.CompressFormat.JPEG, 100, bos);
//			// 调用flush()方法，更新BufferStream
	
	
//			bos.flush();
//			bos.close();
//
//		} catch (Exception e) {
//
//			e.printStackTrace();
//		}
//
//		bitmap.recycle();
//		return bit;
//
//	}

	/**
	 * @param context
	 * @param data
	 * @param imageView
	 * @return
	 */
	/*
	 * 获取图片
	 */
	public static Bitmap getPhoto(Activity context, Intent data,ImageView imageView) {
		context.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
		Bitmap bitmap = null;
		int [] arr = null;
		if (data != null) {
			// 照片的原始资源地址
			Uri originUri = data.getData();
			// 通过URI获取原始图片path 
			/**
			 * Sandy
			 */
//			fileName = getRealPath(context, originUri);
			fileName = getPath(context, originUri);
			arr = 	getWidthHeight(fileName);
		}
		
		if(fileName == null || "null".equals(fileName)){
			return null;
		}
		
		if(arr[0]>3000 || arr[1]>3500){
			bitmap = decodeSampledBitmapFromResource(fileName,displayMetrics.widthPixels/3, displayMetrics.heightPixels/3);
//			bitmap = decodeBitmap(fileName, 50);
		}else{
			bitmap = decodeSampledBitmapFromResource(fileName,displayMetrics.widthPixels, displayMetrics.heightPixels);
//			bitmap = decodeSampledBitmapFromResource(fileName,displayMetrics.widthPixels, displayMetrics.heightPixels);
		
		}
		if(bitmap == null ){
			ToastUtils.show("选择图片出错");
			return null;
		}
		
//		bitmap = decodeBitmap(fileName, 50);
		
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		 
		
		// 是否旋转图片
		int degree = getPictureDegree(fileName);
		if (degree > 0) {
			bitmap = rotaingImage(degree, bitmap);
		}
		Bitmap bit = compressImage(bitmap, MAX_SIZE);
		if (data != null) {
			fileName = getFileName();
		}
		BufferedOutputStream bos;
		try {
			bos = new BufferedOutputStream(new FileOutputStream(fileName));
			// 采用压缩转档方法
			bit.compress(CompressFormat.JPEG, 100, bos);
			// 调用flush()方法，更新BufferStream
			bos.flush();
			bos.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

		bitmap.recycle();
		return bit;
	}
	
	  /** 
     * 采用复杂计算来决定缩放 
     * @param path 
     * @param maxImageSize 
     * @return 
     */  
    public static Bitmap decodeBitmap(String path, int maxImageSize){  
        BitmapFactory.Options op = new BitmapFactory.Options();  
        op.inJustDecodeBounds = true;  
        Bitmap bmp = BitmapFactory.decodeFile(path, op); //获取尺寸信息  
        int scale = 1;  
        if(op.outWidth > maxImageSize || op.outHeight > maxImageSize){  
            scale = (int)Math.pow(2, (int)Math.round(Math.log(maxImageSize/(double)Math.max(op.outWidth, op.outHeight))/Math.log(0.5)));  
        }  
        op.inJustDecodeBounds = false;  
        op.inSampleSize = scale;  
        bmp = BitmapFactory.decodeFile(path, op);  
        return bmp;       
    }  
    
    /*
	 * 按比例缩放图片 根据路径获取图片
	 */
	public static Bitmap decodeSampledBitmapFromResource(String path,int reqWidth, int reqHeight) {
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, options);
		options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, options);
	}
      
	
	public static int[] getWidthHeight(String pathName){		
	       BitmapFactory.Options opts = new BitmapFactory.Options();
           opts.inJustDecodeBounds = true;
           BitmapFactory.decodeFile(pathName, opts);
           opts.inSampleSize = 1;  
           opts.inJustDecodeBounds = false;          
           int width=opts.outWidth;
           int height=opts.outHeight;
           int[] str=  new int[]{width,height};
           return str;
	}

	/*
	 * 获取图片
	 */
	public static byte[] getPhotoBytes(Activity context, Intent data) {
		context.getWindowManager().getDefaultDisplay()
				.getMetrics(displayMetrics);
		Bitmap bitmap = null;
		if (data != null) {
			// 照片的原始资源地址
			Uri originUri = data.getData();
			// 通过URI获取原始图片path
			fileName = getRealPath(context, originUri);
		}

		bitmap = decodeSampledBitmapFromResource(fileName,
				displayMetrics.widthPixels, displayMetrics.heightPixels);
		// 是否旋转图片
		int degree = getPictureDegree(fileName);
		if (degree > 0) {
			bitmap = rotaingImage(degree, bitmap);
		}
		Bitmap bit = compressImage(bitmap, MAX_SIZE);
//		Bitmap bit = comp(bitmap);
	 
		if (data != null) {
			fileName = getFileName();
		}
		BufferedOutputStream bos;
		try {
			bos = new BufferedOutputStream(new FileOutputStream(fileName));
			// 采用压缩转档方法
			bit.compress(CompressFormat.JPEG, 100, bos);
			// 调用flush()方法，更新BufferStream
			bos.flush();
			bos.close();

		} catch (IOException e) {

			e.printStackTrace();
		}

		bitmap.recycle();
		return Bitmap2Bytes(bit);
	}

	/**
	 * 将bitmap转换成byte[];
	 * 
	 * @param bm
	 * @return
	 */
	public static byte[] Bitmap2Bytes(Bitmap bm) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(CompressFormat.JPEG, 100, baos);
		return baos.toByteArray();
	}

	/*
	 * 按质量缩放图片到指定大小
	 */
	public static Bitmap compressImage(Bitmap bitmap, int maxSize) {
		maxSize = 5 ;
		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
		// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到arrayOutputStream中
		bitmap.compress(CompressFormat.JPEG, 100, arrayOutputStream);
		int options = 100;
		// 循环判断如果压缩后图片是否大于maxSize,大于继续压缩
		while (arrayOutputStream.toByteArray().length / 1024 > maxSize
				&& options > 10) {
			options -= 10;// 降低质量
			arrayOutputStream.reset();// 清空数组数据
			if (options > 0 && options <= 100) {
				bitmap.compress(CompressFormat.JPEG, options, arrayOutputStream);// 循环压缩图片
			} else {
				bitmap.compress(CompressFormat.JPEG, 10, arrayOutputStream);// 循环压缩图片
			}
		}
		// 把压缩后的数据arrayOutputStream存放到ByteArrayInputStream中
		ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(arrayOutputStream.toByteArray());
		// 用ByteArrayInputStream数据生成图片
	 
		Drawable drawable = Drawable.createFromStream(arrayInputStream, "image");
		BitmapDrawable bd = (BitmapDrawable)drawable;
//		Bitmap bit = BitmapFactory.decodeStream(arrayInputStream);
		Bitmap bit = bd.getBitmap();
		
		
		
		bitmap.recycle();
		return bit;
	}

	private static Bitmap comp(Bitmap image) {
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();		
		image.compress(CompressFormat.JPEG, 100, baos);
		if( baos.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片（BitmapFactory.decodeStream）时溢出	
			baos.reset();//重置baos即清空baos
			image.compress(CompressFormat.JPEG, 50, baos);//这里压缩50%，把压缩后的数据存放到baos中
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		//开始读入图片，此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		//现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
		float hh = 800f;//这里设置高度为800f
		float ww = 480f;//这里设置宽度为480f
		//缩放比。由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
		int be = 1;//be=1表示不缩放
		if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;//设置缩放比例
		//重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
		isBm = new ByteArrayInputStream(baos.toByteArray());
		bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
		return compressImage(bitmap,MAX_SIZE);//压缩好比例大小后再进行质量压缩
	}
	

	/*
	 * 计算缩放比例
	 */
	private static int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		reqWidth = Math.min(480, reqWidth);
		reqWidth = Math.min(800, reqHeight);
		// height/width of image
		int height = options.outHeight;
		int width = options.outWidth;

		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			while ((halfWidth / inSampleSize) > reqWidth
					&& (halfHeight / inSampleSize) > reqHeight) {
				inSampleSize *= 2;
			}
		}

		return inSampleSize;

	}

	/*
	 * 计算缩放比例
	 */
	private static int calculateInSampleSize1(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// height/width of image
		int height = options.outHeight;
		int width = options.outWidth;

		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			final int heightScale = Math.round((float) height
					/ (float) reqHeight);
			final int widthScale = Math.round((float) width / (float) reqWidth);
			inSampleSize = heightScale > widthScale ? heightScale : widthScale;
		}

		return inSampleSize;

	}

	/*
	 * uri 转 filepath
	 */
	public static String getRealPath(Context context, Uri fileUrl) {
		String fileName = null;
		Uri filePathUri = fileUrl;
		if (fileUrl != null) {
			if (fileUrl.getScheme().toString().compareTo("content") == 0) {
				// content://开头的uri
				  String[] proj = { MediaStore.Images.Media.DATA };
				Cursor cursor = context.getContentResolver().query(fileUrl,
						proj, null, null, null);
				
				if (cursor != null && cursor.moveToFirst()) {
					int column_index = cursor
							.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
					fileName = cursor.getString(column_index); // 取出文件路径
					cursor.close();
				}
			} else if (fileUrl.getScheme().compareTo("file") == 0) {
				// file:///开头的uri
				fileName = filePathUri.toString();
				fileName = filePathUri.toString().replace("file://", "");// 替换file://
			}
		}
		return fileName;
	}

	/**
	 * 获取图片的旋转角度 path
	 */
	private static int getPictureDegree(String path) {
		int degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt(
					ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				degree = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				degree = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				degree = 270;
				break;
			default:
				break;
			}
		} catch (IOException e) {

			e.printStackTrace();
		}
		return degree;
	}

	/**
	 * 旋转图片
	 */
	private static Bitmap rotaingImage(int degree, Bitmap bitmap) {
		// 旋转图片 动作
		Matrix matrix = new Matrix();
		matrix.postRotate(degree);
		// 创建新的图片
		Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
				bitmap.getHeight(), matrix, true);
		bitmap.recycle();
		return newBitmap;
	}


	@SuppressLint("NewApi")
	public static String getPath(final Context context, final Uri uri) {
		  int i = 0;
         System.out.println(uri.toString() + i);
		final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 

	    // Document  Provider
	    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
	        // ExternalStorageProvider
	        if (isExternalStorageDocument(uri)) {
	            final String docId = DocumentsContract.getDocumentId(uri);
	            final String[] split = docId.split(":");
	            final String type = split[0];

	            if ("primary".equalsIgnoreCase(type)) {
	                return Environment.getExternalStorageDirectory() + "/" + split[1];
	            }

	            // TODO handle non-primary volumes
	        }
	        // DownloadsProvider
	        else if (isDownloadsDocument(uri)) {

	            final String id = DocumentsContract.getDocumentId(uri);
	            final Uri contentUri = ContentUris.withAppendedId(
	                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

	            return getDataColumn(context, contentUri, null, null);
	        }
	        // MediaProvider
	        else if (isMediaDocument(uri)) {
	            final String docId = DocumentsContract.getDocumentId(uri);
	            final String[] split = docId.split(":");
	            final String type = split[0];

	            Uri contentUri = null;
	            if ("image".equals(type)) {
	                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
	            } else if ("video".equals(type)) {
	                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
	            } else if ("audio".equals(type)) {
	                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
	            }

	            final String selection = "_id=?";
	            final String[] selectionArgs = new String[] {
	                    split[1]
	            };

	            return getDataColumn(context, contentUri, selection, selectionArgs);
	        }
	    }
	    // MediaStore (and general)
	    else if ("content".equalsIgnoreCase(uri.getScheme())) {

	        // Return the remote address
	        if (isGooglePhotosUri(uri))
	            return uri.getLastPathSegment();

	        return getDataColumn(context, uri, null, null);
	    }
	    // File
	    else if ("file".equalsIgnoreCase(uri.getScheme())) {
	        return uri.getPath();
	    }

	    return null;
	}

	/**
	 * Get the value of the data column for this Uri. This is useful for
	 * MediaStore Uris, and other file-based ContentProviders.
	 *
	 * @param context The context.
	 * @param uri The Uri to query.
	 * @param selection (Optional) Filter used in the query.
	 * @param selectionArgs (Optional) Selection arguments used in the query.
	 * @return The value of the _data column, which is typically a file path.
	 */
	public static String getDataColumn(Context context, Uri uri, String selection,
	        String[] selectionArgs) {

	    Cursor cursor = null;
	    final String column = "_data";
	    final String[] projection = {
	            column
	    };

	    try {
	        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
	                null);
	        if (cursor != null && cursor.moveToFirst()) {
	            final int index = cursor.getColumnIndexOrThrow(column);
	            return cursor.getString(index);
	        }
	    } finally {
	        if (cursor != null)
	            cursor.close();
	    }
	    return null;
	}


	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is ExternalStorageProvider.
	 */
	public static boolean isExternalStorageDocument(Uri uri) {
	    return "com.android.externalstorage.documents".equals(uri.getAuthority());
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is DownloadsProvider.
	 */
	public static boolean isDownloadsDocument(Uri uri) {
	    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is MediaProvider.
	 */
	public static boolean isMediaDocument(Uri uri) {
	    return "com.android.providers.media.documents".equals(uri.getAuthority());
	}

	/**
	 * @param uri The Uri to check.
	 * @return Whether the Uri authority is Google Photos.
	 */
	public static boolean isGooglePhotosUri(Uri uri) {
	    System.out.println("uriAuthority:"+uri.getAuthority());
	    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
	}
	
	

}
